﻿#region << 文 件 说 明 >>

/*----------------------------------------------------------------
// 文件名称：WindowBase
// 创 建 者：杨程
// 创建时间：2021/10/11 14:00:27
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/

#endregion

namespace Vampirewal.Core.WPF.Theme;

/// <summary>
/// 自定义窗体基类
/// </summary>
public class WindowBase : Window, IWindows, IDisposable
{
    private Button CloseButton { get; set; }
    private Button MinButton;

    public UIElement MainContent { get; set; }

    /// <summary>
    /// 顶部自定义按钮区域
    /// </summary>
    public List<UIElement> TopCustomButtons { get; set; } = new List<UIElement>();

    /// <summary>
    /// 底部自定义内容区域
    /// </summary>
    public List<UIElement> BottomCustomAreas { get; set; } = new List<UIElement>();

    /// <summary>
    /// 数据上下文
    /// </summary>
    public virtual ViewModelBase DataSource { get; set; }

    /// <summary>
    /// 窗体ID
    /// </summary>
    public Guid ViewId { get; set; }

    public virtual string ViewModelKey { get; }

    protected ResourceDictionary res
    {
        get
        {
            return new ResourceDictionary() { Source = new Uri("pack://application:,,,/Vampirewal.Core.WPF.Theme;component/Theme.xaml", UriKind.RelativeOrAbsolute) };
        }
    }

    static WindowBase()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowBase), new FrameworkPropertyMetadata(typeof(WindowBase)));
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    public WindowBase()
    {
        this.Loaded += Window_Loaded;
        WindowStartupLocation = WindowStartupLocation.CenterScreen;

        ViewId = Guid.NewGuid();

        var BaseStyle = res["WindowBase"] as Style;

        this.Style = BaseStyle;

        this.IsVisibleChanged += WindowBase_IsVisibleChanged;
    }

    private void WindowBase_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            if (DataSource != null)
            {
                //DataSource.View = Window.GetWindow(this);
                DataSource.ViewId = ViewId;
                SetValue(FrameworkElement.DataContextProperty, DataSource);
            }
        }
    }

    protected virtual void Window_Loaded(object sender, RoutedEventArgs e)
    {
        WindowsLoadedCommand?.Execute(null);
    }

    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        //var aaa = base.Resources["WindowBase"] as Style;//如果前端添加引用之后，可以使用这个方法

        CloseButton = this.Template.FindName("btn_CloseWindow", this) as Button;
        var MaxWin = this.Template.FindName("btn_MaxWindow", this) as ToggleButton;
        MinButton = this.Template.FindName("btn_MinWindow", this) as Button;

        if (CloseButton != null && MaxWin != null && MinButton != null)
        {
            CloseButton.Click += CloseWin_Click;

            MaxWin.Checked += MaxWin_Checked;
            MaxWin.Unchecked += MaxWin_Unchecked;

            MinButton.Click += MinWin_Click;
        }

        var TopTitle = this.Template.FindName("TopTitle", this) as Border;
        TopTitle.MouseLeftButtonDown += TopTitle_MouseLeftButtonDown;

        var border = this.Template.FindName("border", this) as Border;
        border.Margin = new Thickness(1);
        border.MaxHeight = SystemParameters.WorkArea.Height - 5;
        border.MaxWidth = SystemParameters.WorkArea.Width - 5;

        var TopLayoutBtns = this.Template.FindName("TopCustomButtons", this) as StackPanel;
        foreach (var item in TopCustomButtons)
        {
            TopLayoutBtns.Children.Add(item);
        }

        var BottomCustomArea = this.Template.FindName("BottomCustomArea", this) as Grid;
        //BottomCustomArea.Height = 0;
        if (BottomCustomAreas.Count > 0)
        {
            BottomCustomArea.SetValue(Grid.HorizontalAlignmentProperty, BottomHorizontalAlignment);

            //BottomCustomArea.Height = 50;
            foreach (var item in BottomCustomAreas)
            {
                BottomCustomArea.Children.Add(item);
            }
        }

        //this.ResizeMode = ResizeMode.CanResize;
    }

    /// <summary>
    /// 自定义窗体标题栏鼠标左键按下事件（可重写）
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected virtual void TopTitle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        this.DragMove();
    }

    private void MinWin_Click(object sender, RoutedEventArgs e)
    {
        this.WindowState = WindowState.Minimized;
    }

    private void MaxWin_Unchecked(object sender, RoutedEventArgs e)
    {
        this.WindowState = WindowState.Normal;
    }

    private void MaxWin_Checked(object sender, RoutedEventArgs e)
    {
        this.WindowState = WindowState.Maximized;
    }

    /// <summary>
    /// 关闭窗体（可重写，需保留base.CloseWin_Click）
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected virtual void CloseWin_Click(object sender, RoutedEventArgs e)
    {
        CloseWindowCommand?.Execute(CloseWindowCommandParameter);

        //WindowsManager.GetInstance().CloseWindow(this);
        this.Close();
        GC.Collect();
    }

    //protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    //{
    //    //DragMove();
    //    base.OnMouseDown(e);
    //}

    #region 依赖属性

    #region 标题文字

    /// <summary>
    /// 标题文字大小
    /// </summary>
    public int TitleFontSize
    {
        get { return (int)GetValue(TitleFontSizeProperty); }
        set { SetValue(TitleFontSizeProperty, value); }
    }

    /// <summary>
    /// 标题文字大小
    /// </summary>
    // Using a DependencyProperty as the backing store for TitleFontSize.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleFontSizeProperty =
        DependencyProperty.Register("TitleFontSize", typeof(int), typeof(WindowBase), new PropertyMetadata(12));

    /// <summary>
    /// 标题前景色
    /// </summary>
    public Brush TitleForeground
    {
        get { return (Brush)GetValue(TitleForegroundProperty); }
        set { SetValue(TitleForegroundProperty, value); }
    }

    /// <summary>
    /// 标题前景色
    /// </summary>
    // Using a DependencyProperty as the backing store for TitleForeground.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleForegroundProperty =
        DependencyProperty.Register("TitleForeground", typeof(Brush), typeof(WindowBase), new PropertyMetadata(Brushes.White));

    #endregion

    #region 是否启用窗体调整

    public bool IsOpenWindowSize
    {
        get { return (bool)GetValue(IsOpenWindowSizeProperty); }
        set { SetValue(IsOpenWindowSizeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsOpenWindowSize.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsOpenWindowSizeProperty =
        DependencyProperty.Register("IsOpenWindowSize", typeof(bool), typeof(WindowBase), new PropertyMetadata(false, IsOpenWindowSizePropertyChangeCallBack));

    private static void IsOpenWindowSizePropertyChangeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        bool value = Convert.ToBoolean(e.NewValue);
        if (value)
        {
            Window w = (Window)d;
            w.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            w.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
            w.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
            w.WindowState = WindowState.Normal;
            WindowChrome chrome = new WindowChrome();
            chrome.CornerRadius = new CornerRadius(5);
            chrome.GlassFrameThickness = new Thickness(1, 0, 1, 1);
            chrome.UseAeroCaptionButtons = false;
            chrome.NonClientFrameEdges = NonClientFrameEdges.None;
            chrome.CaptionHeight = 2;

            WindowChrome.SetWindowChrome(w, chrome);
        }
    }



    #endregion

    #region 是否显示最小化

    public bool IsShowMinButton
    {
        get { return (bool)GetValue(IsShowMinButtonProperty); }
        set { SetValue(IsShowMinButtonProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsShowMinButton.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsShowMinButtonProperty =
        DependencyProperty.Register("IsShowMinButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(true));

    #endregion

    #region 是否显示最大化按钮

    public bool IsShowMaxButton
    {
        get { return (bool)GetValue(IsShowMaxButtonProperty); }
        set { SetValue(IsShowMaxButtonProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsShowMaxButton.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsShowMaxButtonProperty =
        DependencyProperty.Register("IsShowMaxButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(true));

    #endregion

    #region 是否显示关闭按钮

    public bool IsShowCloseButton
    {
        get { return (bool)GetValue(IsShowCloseButtonProperty); }
        set { SetValue(IsShowCloseButtonProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsShowCloseButton.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsShowCloseButtonProperty =
        DependencyProperty.Register("IsShowCloseButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(true));

    #endregion

    #region 是否显示边框阴影

    //public bool IsShowDropShadowEffect
    //{
    //    get { return (bool)GetValue(IsShowDropShadowEffectProperty); }
    //    set { SetValue(IsShowDropShadowEffectProperty, value); }
    //}

    //// Using a DependencyProperty as the backing store for IsShowDropShadowEffect.  This enables animation, styling, binding, etc...
    //public static readonly DependencyProperty IsShowDropShadowEffectProperty =
    //    DependencyProperty.Register("IsShowDropShadowEffect", typeof(bool), typeof(WindowBase), new PropertyMetadata(false, IsShowDropShadowEffectPropertyChangeCallBack));

    //private static void IsShowDropShadowEffectPropertyChangeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    //{
    //}

    #endregion

    #region 关闭窗体触发事件

    /// <summary>
    /// 关闭窗体触发命令
    /// </summary>
    public ICommand CloseWindowCommand
    {
        get { return (ICommand)GetValue(CloseWindowCommandProperty); }
        set { SetValue(CloseWindowCommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CloseWindowCommand.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CloseWindowCommandProperty =
        DependencyProperty.Register("CloseWindowCommand", typeof(ICommand), typeof(WindowBase), new PropertyMetadata(null));

    public object CloseWindowCommandParameter
    {
        get { return (object)GetValue(CloseWindowCommandParameterProperty); }
        set { SetValue(CloseWindowCommandParameterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CloseWindowCommandParameter.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CloseWindowCommandParameterProperty =
        DependencyProperty.Register("CloseWindowCommandParameter", typeof(object), typeof(WindowBase), new PropertyMetadata(null));

    #endregion

    #region 窗体Loaded事件

    /// <summary>
    /// 窗体Loaded触发命令
    /// </summary>
    public ICommand WindowsLoadedCommand
    {
        get { return (ICommand)GetValue(WindowsLoadedCommandProperty); }
        set { SetValue(WindowsLoadedCommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for WindowsLoadedCommand.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WindowsLoadedCommandProperty =
        DependencyProperty.Register("WindowsLoadedCommand", typeof(ICommand), typeof(WindowBase), new PropertyMetadata(null));

    #endregion

    #region 底部自定义区域靠左还是右


    /// <summary>
    /// 底部自定义区域靠左还是右
    /// </summary>
    public HorizontalAlignment BottomHorizontalAlignment
    {
        get { return (HorizontalAlignment)GetValue(BottomHorizontalAlignmentProperty); }
        set { SetValue(BottomHorizontalAlignmentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for BottomHorizontalAlignment.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BottomHorizontalAlignmentProperty =
        DependencyProperty.Register("BottomHorizontalAlignment", typeof(HorizontalAlignment), typeof(WindowBase), new PropertyMetadata(HorizontalAlignment.Left));



    #endregion

    #endregion


    /// <summary>
    /// 释放
    /// </summary>
    public virtual void Dispose()
    {

    }
}